package com.example.controllibrary;

import android.os.Handler;
import android.os.IInterface;
import android.os.Message;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android_serialport_api.SerialPort;

public class LockControl {

    private static final String TAG = "LockControl";

    private static SerialPort mSerialPort;
    private static OutputStream mOutputStream;
    private static boolean isConnected = false;

    private static electrolStatusCallback statusCallback;

    private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    private static Timer statusTimer = null;
    private static statusTimeTask statusTimeTask = null;
    private static boolean isCompleted = false;
    private static List<Byte> bufferList = new ArrayList();
    private static int FlagsFive = 0;

    public static boolean GetIsConnected() {
        return isConnected;
    }

    public static boolean OpenSerialPort(String path, int baudrate, electrolStatusCallback callback) {
        if(isConnected && mSerialPort != null)
        {
            return true;
        }
        try {
            mSerialPort = new SerialPort(new File(path), baudrate, 0);
            mOutputStream = mSerialPort.getOutputStream();
            isConnected = true;
            statusCallback = callback;
            cachedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    InputStream is = mSerialPort.getInputStream();
                    while (isConnected) {
                        try {
                            if (null == is) {
                                Log.d("LockControl", "ReadThread inputstream is null break");
                                continue;
                            }

                            byte[] bufferx = new byte[20];
                            int byteCount = is.read(bufferx);
//                            Log.e("读到数据长度", "读到数据长度" + byteCount);

                            if (byteCount > 0) {
                                for (int len = 0; len < byteCount; len++) {
//                                    FlagsFive++;
                                    Log.e(TAG, "数据缓存：= " + bufferList.size() + "， " + Integer.toHexString(bufferx[len] & 0xFF));
                                    switch (bufferList.size()){
                                        case 0:
                                            if(bufferx[len] == (byte)0x80){
                                                bufferList.add(bufferx[len]);
                                            }
                                            break;
                                        case 1:
                                        case 2:
                                            if(bufferx[len] == (byte)0x01){
                                                bufferList.add(bufferx[len]);
                                            }
                                            break;
                                        case 3:
                                            if(bufferx[len] == (byte)0x00){
                                                bufferList.add(bufferx[len]);
                                            }
                                            break;
                                        case 4:
                                            byte tmp = (byte)(bufferList.get(0) ^ bufferList.get(1) ^ bufferList.get(2) ^ bufferList.get(3));
                                            if(bufferx[len] == tmp){
                                                bufferList.add(bufferx[len]);
                                                isCompleted = true;
                                            }
                                            break;
                                        default:
                                            break;
                                    }
//                                    if(5 == FlagsFive){
//                                        if(!isCompleted){
//                                            bufferList.clear();
//                                            FlagsFive = 0;
//                                        }
//                                    }
//                                    Log.e("数据", len + "= " + Integer.toHexString(bufferList.get(len) & 0xFF));
                                }
                            }
//                            Log.e("缓存数据大小", bufferList.size() + " ");
                            if (bufferList.size() >= 5) {
                                for(int i = 0; i < bufferList.size(); i++){
                                    Log.e(TAG, i + "= " + Integer.toHexString(bufferList.get(i) & 0xFF));
                                }
                                if(bufferList.get(0) == (byte)0x80) {
                                    if(bufferList.get(1) == (byte)0x01){
                                        if (bufferList.get(2) == (byte) 0x01) {
                                            if(bufferList.get(3) == (byte)0x00){
                                                statusCallback.onResult(true);
                                                statusTimer.cancel();
                                                statusTimer = null;
                                                statusTimeTask = null;
                                                Log.e(TAG, "关闭定时器");
                                                isCompleted = true;
                                            }else {
                                                isCompleted = true;
                                            }
                                        }else{
                                            isCompleted = true;
                                        }
                                    }else{
                                        isCompleted = true;
                                    }
                                }else if(bufferList.get(0) == (byte)0x70){
                                    isCompleted = true;
                                }
                            }else{
                                isCompleted = false;
                            }
                        } catch (IOException var6) {
                            Log.d("LockControl", "ReadThread IOException e: " + var6.toString());
                            var6.printStackTrace();
                        }
                        if(isCompleted){
                            bufferList.clear();
                            isCompleted = false;
                            Log.e(TAG, "结束");
                        }
                    }
                }
            });
            Thread.sleep(100);
            Log.i("DeviceAPI", "serialport open success");
        } catch (IOException var6) {
            Log.i("DeviceAPI", "serialport open fail");
        } catch (SecurityException var7) {
            Log.i("DeviceAPI", "serialport open fail , permission denied");
        } catch (InvalidParameterException var8) {
            Log.i("DeviceAPI", "serialport open fail , invalid param");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return isConnected;
    }

    public static void Close() {
        try {
            isConnected = false;
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mSerialPort.closeStream();
            mSerialPort.close();
            mOutputStream.close();

            mSerialPort = null;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void SendMessage(byte[] data) {
        if (isConnected) {
            try {
                mOutputStream.write(data);
                mOutputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /*
        锁控板通信协议  7A指令下发打开是持续供电，8A指令下发打开是产生瞬间电流
        0x00    表示关闭
        0x11    表示打开
     */

    //电磁锁控制LK1
    public static boolean electroLockCControl(byte value){
        byte[] data = new byte[]{(byte)0x7A, (byte)0x01, (byte)0x01, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);
        //当触发关门动作，开始查询电磁锁状态
        if(0x00 == value){
            bufferList.clear();
            SendMessage(data);
            if(null != statusTimer){
                Log.e(TAG, "取消定时器");
                statusTimer.cancel();
                statusTimer = null;
                statusTimeTask = null;
            }
            statusTimer = new Timer();
            statusTimeTask = new statusTimeTask();
            statusTimer.schedule(statusTimeTask, 0, 1000);
            Log.e(TAG, "开启定时器");
        }
        if(0x11 == value){
            bufferList.clear();
            SendMessage(data);
            Log.e(TAG, "开电磁锁");
        }

        return true;
    }

    //查询电磁锁状态
    private static void checkElectrolCStatus(){
        byte[] data = new byte[]{(byte)0x80, (byte)0x01, (byte)0x01, (byte)0x33, (byte)0x00};
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);
//        bufferList.clear();

        SendMessage(data);
    }

    //查询电磁锁状态回调接口
    public interface electrolStatusCallback {
        void onResult(boolean res);
    }

    //电钩锁控制LK2
    public static boolean electroLockGControl(byte value){
        byte[] data = new byte[]{(byte)0x8A, (byte)0x01, (byte)0x02, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);
        Log.e(TAG, "开电钩锁");
        bufferList.clear();
        SendMessage(data);
        return true;
    }



    //LED灯控制LK3
    public static boolean ledControl(byte value){
        byte[] data = new byte[]{(byte)0x7A, (byte)0x01, (byte)0x03, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);
        if(0x00 == value){
            Log.e(TAG, "关灯");
        }
        if(0x11 == value){
            Log.e(TAG, "开灯");
        }
        bufferList.clear();
        SendMessage(data);
        return true;
    }

    //排风扇控制LK4
    public static boolean pfanControl(byte value){
        byte[] data = new byte[]{(byte)0x7A, (byte)0x01, (byte)0x04, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);

        SendMessage(data);
        return true;
    }

    //鼓风机控制LK5  抽风机控制
    public static boolean gfanControl(byte value){
        byte[] data = new byte[]{(byte)0x7A, (byte)0x01, (byte)0x05, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);

        SendMessage(data);
        return true;
    }

    //消毒机开关LK6
    public static boolean cfanControl(byte value){
        byte[] data = new byte[]{(byte)0x8A, (byte)0x01, (byte)0x06, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);

        SendMessage(data);
        return true;
    }

    //杀毒模式LK7
    public static boolean otherfanControl(byte value){
        byte[] data = new byte[]{(byte)0x8A, (byte)0x01, (byte)0x07, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);

        SendMessage(data);
        return true;
    }

    //等离子模式LK8
    public static boolean reserverfanControl(byte value){
        byte[] data = new byte[]{(byte)0x8A, (byte)0x01, (byte)0x08, (byte)0x99, (byte)0x00};
        data[3] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);

        SendMessage(data);
        return true;
    }

    //查询各部件状态
    //  0x00        表示关闭状态
    //  0x11        表示打开状态
    public static boolean checkAll(byte value){
        byte[] data = new byte[]{(byte)0x80, (byte)0x01, (byte)0x01, (byte)0x33, (byte)0x00};
        data[2] = value;
        data[4] = (byte)(data[0] ^ data[1]^ data[2]^ data[3]);

        SendMessage(data);
        return true;
    }

    static class statusTimeTask extends TimerTask{

        @Override
        public void run() {
            checkElectrolCStatus();
        }
    }

}
